/**
 * Created by chengming on 18/4/18.
 * version 1.0
 */
'use strict';
const logger = require('../../conf/logger');
const request = require('request-promise');
const cheerio = require('cheerio');
const moment = require('moment');
const urlTool = require('url');
const server = require('../../conf/server');
const iconv = require("iconv-lite");
const JSONSelect = require('JSONSelect');
const report = require('../../exception/ErrorReport');
const contentReport = require('../../exception/ContentReport');
const BaseAdapter = require('./BaseAdapter');

class BaseJsonAdapter extends BaseAdapter{

	constructor(page, isTest){
		super(page, page.encoding || "UTF-8", isTest, false);

		this.pageTitle = page.pageTitle;
		this.linkRule = page.linkRule;

		this.channel = page.channel;
		this.cates = page.cates;
		this.foreign = page.foreign;

		this.titleRule = page.titleRule;
		this.contentRule = page.contentRule;

		this.linkUniqueBy = page.linkUniqueBy||1;
		this.followLink = page.followLink;
		this.sourceTime = page.createtime;
		this.pageSite = page.pageSite;

        this.id = page.id;
        this.rangeMd5 = page.rangeMd5;
	}

	async reqJson(){
	}

	selectNode(node, rule){
        if(rule.indexOf(".") != -1){
            let propRules = rule.split(".");
            let res = node;
            for(let i = 0; i < propRules.length; i++){
                res = res[ propRules[i] ];
            }
            return res;
        }
        return node[rule];
	}

	async execute(){
		logger.debug('开始执行抓取->'+this.pageName);

		let selectedBody = await this.reqJson();

		let decodeBody = selectedBody;

		logger.debug("-------------------------"+this.pageName+"的请求结果body为:"+ JSON.stringify(selectedBody));

		logger.debug(this.pageTitle + '抓取执行完毕,开始分析文本');

		if(this.linkRule.length == 0){
			logger.warn(this.pageName + '没有json内容规则');
			if(!this.isTest){
				await report(this.pageSite, this.pageTitle, '', '没有json内容规则');
			}
			return {
				code: 401,
				errMsg: '没有json内容规则'
			};
		}

		let [jsonArr, jsonTitle, jsonHref ] = this.linkRule.split('#');

		if(jsonArr.length == 0){
			logger.warn(this.pageName +'json数组属性不存在');
			if(!this.isTest){
				await report(this.pageSite, this.pageTitle, '', 'json数组属性不存在');
			}
			return {
				code: 402,
				errMsg: 'json数组属性不存在'
			}
		}

		let props = jsonArr.split('.');
		logger.debug(this.pageName+"使用以下属性取出数组对象"+JSON.stringify(props));


		let propLen = props.length;
		for(let i = 0; i < propLen; i++){
			selectedBody = selectedBody[ props[i] ];
			if(i != propLen - 1 && selectedBody instanceof Array){
				//如果属性中为数组,则默认取出第一个元素
				selectedBody = selectedBody[0];
			}
			if(!selectedBody){
				logger.error(this.pageName+"对象中没有"+props[i]+"属性");
				if(!this.isTest){
					await report(this.pageSite, this.pageTitle, '', "对象中没有"+props[i]+"属性");
				}
				return {
					code: 403,
					errMsg: "对象中没有"+props[i]+"属性"
				}
			}
		}

		let contents = [];
		let that = this;
		let rangeText = '';

		for(let item of selectedBody) {
            let title = this.selectNode(item, jsonTitle);

			let href = '';
			if(jsonHref.startsWith("`")){
                href = jsonHref.replace(/`/g, '');
				//正则表达式提取参数
                let params = href.match(/\{(.*?)\}/g);
                if(params){
                    for(let param of params){
                        href = href.replace(new RegExp(param, 'g'), item[param.replace(/[\{\}]+/g, '')]);
                    }
				}

			}else if(href = this.selectNode(item, jsonHref)){
				href = urlTool.resolve(that.requestUrl, href);
			}

			contents.push({
				title:title,
				href:href
			});
			rangeText +=title+href;
		};

		if(rangeText.length == 0){
			logger.warn(this.pageName+"->"+this.linkRule+"此抓取规则下,无内容匹配");
			if(!this.isTest){
				await report(this.pageSite, this.pageTitle, '', this.linkRule+"此抓取规则下,无内容匹配 " + selectedBody);
			}
			return {
				code: 406,
				errMsg: this.linkRule+"此抓取规则下,无内容匹配 " + selectedBody
			}
		}

        await super.postSocket(this.id, this.rangeMd5, rangeText, contents,  decodeBody, this.cates, this.pageTitle, this.sourceTime, this.channel,
			this.followLink, this.foreign, this.contentRule, this.linkUniqueBy);

        return await this.postFilterUnique(contents,
			this.cates,
			this.foreign,
			this.linkUniqueBy,
			this.followLink,
			this.sourceTime,
			this.pageTitle,
			this.titleRule,
			this.contentRule,
			this.channel);
	}
	
}

module.exports = BaseJsonAdapter;